/*  
    Copyright 2010 Mike Eheler <mike.eheler@gmail.com>

    This file is part of Four Falling Blocks Puzzle Game.

    Four Falling Blocks Puzzle Game is free software: you can
	redistribute it and/or modify it under the terms of the GNU General
	Public License as published by the Free Software Foundation, either
	version 3 of the License, or (at your option) any later version.

    Four Falling Blocks Puzzle Game is distributed in the hope that it
	will be useful, but WITHOUT ANY WARRANTY; without even the implied
	warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
	See the GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Four Falling Blocks Puzzle Game.
	
	If not, see <http://www.gnu.org/licenses/>.
*/

#include "pieces.h"

Piece::Piece()
{
	memset( mShape, 0, sizeof(uint8_t) * 16 );
}

Piece::Piece( Piece const & that )
{
	memcpy( mShape, that.mShape, sizeof(uint8_t) * 16 );
}

Piece::~Piece()
{
}

Piece & Piece::operator=( Piece const & that )
{
	memcpy( mShape, that.mShape, sizeof(uint8_t) * 16 );
	return *this;
}

bool Piece::operator==( Piece const & that )
{
	for( size_t y = 0; y < 4; y++ )
		for( size_t x = 0; x < 4; x++ )
			if( mShape[y][x] != that.mShape[y][x] )
				return false;

	return true;
}

// Generic rotate (in 3x3 upper-left)
void Piece::rotateLeft()
{
	if( rotates() )
	{
		uint8_t source[4][4];
		memcpy( source, mShape, sizeof(uint8_t) * 16 );
		mShape[0][0] = source[0][2];
		mShape[0][1] = source[1][2];
		mShape[0][2] = source[2][2];
		mShape[1][0] = source[0][1];
		mShape[1][2] = source[2][1];
		mShape[2][0] = source[0][0];
		mShape[2][1] = source[1][0];
		mShape[2][2] = source[2][0];
	}
}

void Piece::rotateRight()
{
	if( rotates() )
	{
		uint8_t source[4][4];
		memcpy( source, mShape, sizeof(uint8_t) * 16 );
		mShape[0][0] = source[2][0];
		mShape[0][1] = source[1][0];
		mShape[0][2] = source[0][0];
		mShape[1][0] = source[2][1];
		mShape[1][2] = source[0][1];
		mShape[2][0] = source[2][2];
		mShape[2][1] = source[1][2];
		mShape[2][2] = source[0][2];
	}
}

// I //
PieceI::PieceI()
{
	// > 0 = block
	// 2 = reserved (anchor?)
	uint8_t shape[4][4] = 
	{
		{ 0, 0, 0, 0 },
		{ 1, 2, 1, 1 },
		{ 0, 0, 0, 0 },
		{ 0, 0, 0, 0 }
	};
	memcpy( mShape, shape, sizeof(uint8_t) * 16 );
}

void PieceI::rotateLeft()
{
	if( rotates() )
	{
		uint8_t source[4][4];
		memcpy( source, mShape, sizeof(uint8_t) * 16 );
		mShape[0][1] = source[1][0]; mShape[1][0] = source[0][1];
		mShape[1][2] = source[2][1]; mShape[2][1] = source[1][2];
		mShape[1][3] = source[3][1]; mShape[3][1] = source[1][3];
	}
}

// J //
PieceJ::PieceJ()
{
	uint8_t shape[4][4] =
	{
		{ 0, 0, 0, 0 },
		{ 1, 2, 1, 0 },
		{ 0, 0, 1, 0 },
		{ 0, 0, 0, 0 }
	};
	memcpy( mShape, shape, sizeof(uint8_t) * 16 );
}

PieceL::PieceL()
{
	uint8_t shape[4][4] =
	{
		{ 0, 0, 0, 0 },
		{ 1, 2, 1, 0 },
		{ 1, 0, 0, 0 },
		{ 0, 0, 0, 0 }
	};
	memcpy( mShape, shape, sizeof(uint8_t) * 16 );
}

PieceO::PieceO()
{
	uint8_t shape[4][4] =
	{
		{ 0, 0, 0, 0 },
		{ 0, 2, 1, 0 },
		{ 0, 1, 1, 0 },
		{ 0, 0, 0, 0 }
	};
	memcpy( mShape, shape, sizeof(uint8_t) * 16 );
}

PieceS::PieceS()
{
	uint8_t shape[4][4] =
	{
		{ 0, 0, 0, 0 },
		{ 0, 2, 1, 0 },
		{ 1, 1, 0, 0 },
		{ 0, 0, 0, 0 }
	};
	memcpy( mShape, shape, sizeof(uint8_t) * 16 );
}

void PieceS::rotateLeft()
{
	if( rotates() )
	{
		uint8_t source[4][4];
		memcpy( source, mShape, sizeof(uint8_t) * 16 );
		mShape[0][1] = 1 - source[0][1];
		mShape[2][0] = 1 - source[2][0];
		mShape[2][1] = 1 - source[2][1];
		mShape[2][2] = 1 - source[2][2];
	}
}

void PieceS::rotateRight()
{
	rotateLeft();
}

PieceT::PieceT()
{
	uint8_t shape[4][4] =
	{
		{ 0, 0, 0, 0 },
		{ 1, 2, 1, 0 },
		{ 0, 1, 0, 0 },
		{ 0, 0, 0, 0 }
	};
	memcpy( mShape, shape, sizeof(uint8_t) * 16 );
}

PieceZ::PieceZ()
{
	uint8_t shape[4][4] =
	{
		{ 0, 0, 0, 0 },
		{ 1, 2, 0, 0 },
		{ 0, 1, 1, 0 },
		{ 0, 0, 0, 0 }
	};
	memcpy( mShape, shape, sizeof(uint8_t) * 16 );
}

void PieceZ::rotateLeft()
{
	if( rotates() )
	{
		uint8_t source[4][4];
		memcpy( source, mShape, sizeof(uint8_t) * 16 );
		mShape[0][2] = 1 - source[0][2];
		mShape[1][0] = 1 - source[1][0];
		mShape[1][2] = 1 - source[1][2];
		mShape[2][2] = 1 - source[2][2];
	}
}

void PieceZ::rotateRight()
{
	rotateLeft();
}
